#include <dblib.h>
#include <stdafx.h>
#include <constants.h>
#include <params.h>
#include <stdexcept>

#ifdef __cplusplus
extern "C" {
#endif

RETCODE __declspec(dllexport) xp_propercase(SRV_PROC *srvproc);

#ifdef __cplusplus
}
#endif

RETCODE __declspec(dllexport) xp_propercase(SRV_PROC *srvproc)
{
	params *p1 = new params();
	params *p2 = new params();
	BYTE *source = NULL;
	BYTE *dest = NULL;
	RETCODE rc = XP_NOERROR;
	int numparams = params::getparamcount(srvproc);
	try
	{
		if (numparams != 2) {
			Dblib::printerror(srvproc, USAGE_PROPERCASE);
			rc = XP_ERROR;
		}
		if (rc == XP_NOERROR) {
			params::getparam(srvproc, 1, p1);
			params::getparam(srvproc, 2, p2);
			if (p1->isoutput || !p2->isoutput) {
				Dblib::printerror(srvproc, USAGE_PROPERCASE);
				rc = XP_ERROR;
			}
		}
		if (rc == XP_NOERROR) {
			dest = new BYTE [p1->length + 1];
			source = p1->cdata;
			*(dest + p1->length) = 0;
			bool start_word = true;
			for (ULONG i = 0; i < p1->length; i++) {
				if (*(source + i) == ' ' || *(source + i) == '.' || *(source + i) == '-' || 
					*(source + i) == '!' || *(source + i) == '?' || *(source + i) == ';' ||
					*(source + i) == ',' || *(source + i) == '(' || *(source + i) == ')' ||
					*(source + i) == '_' || *(source + i) == '&' || *(source + i) == ':' ||
					*(source + i) == '/' || *(source + i) == '.' ||
					(*(source + i) >= '0' && *(source + i) <= '9')) 
				{
					start_word = true;
					*(dest + i) = *(source + i);
				} else if (*(source + i) >= 'a' && *(source + i) <= 'z') {
					if (start_word) {
						*(dest + i) = *(source + i) - 'a' + 'A';
						start_word = false;
					} else {
						*(dest + i) = *(source + i);
					}
				} else if (*(source + i) >= 'A' && *(source + i) <= 'Z') {
					if (start_word) {
						*(dest + i) = *(source + i);
						start_word = false;
					} else {
						*(dest + i) = *(source + i) - 'A' + 'a';
					}
				} else {
					*(dest + i) = *(source + i);
				}
			}
		}
	} catch (std::exception ex) {
		Dblib::printerror(srvproc, ERR_PROPERCASE_EXCEPTION);
		rc = XP_ERROR;
	}
	if (rc == XP_NOERROR)
		srv_paramsetoutput(srvproc, 2, dest, p1->length, FALSE);
	else
		srv_paramsetoutput(srvproc, 2, (BYTE *)"", 0, TRUE);
	srv_senddone(srvproc, SRV_DONE_MORE, (DBUSMALLINT)0, (DBINT)0);	
	if (dest != NULL)
		delete [] dest;
	dest = NULL;
	if (p1 != NULL)
		delete p1;
	p1 = NULL;
	if (p2 != NULL)
		delete p2;
	p2 = NULL;
	return rc;
}

